﻿using Newtonsoft.Json;
using SetPriceCalculateV1d0;
using SetPriceCalculateV1d0.Entity;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PriceCalculateTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public static ItemPriceInfoSetV1d0 ItemOrderedPriceInfoSet { get; set; }
        public static ItemSetPriceRuleSetV1d0 ItemSetPriceRuleSet { get; set; }
        public float[,] RuleArray = new float[2, 2];

        private void button1_Click(object sender, EventArgs e)
        {
            //套餐规则表
            ItemSetPriceRuleSet = new ItemSetPriceRuleSetV1d0();
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule1", 101, 1001, 2));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule2", 101, 1002, 5));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule3", 101, 1003, 25));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule4", 101, 1004, 30));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule5", 101, 1005, 20));

            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule1", 102, 1001, 3));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule2", 102, 1002, 4));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule3", 102, 1003, 30));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule4", 102, 1004, 50));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule5", 102, 1005, 55));


            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule1", 103, 1001, 90));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule2", 103, 1002, 80));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule3", 103, 1003, 70));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule4", 103, 1004, 60));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule5", 103, 1005, 10));


            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule1", 104, 1001, 100));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule2", 104, 1002, 105));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule3", 104, 1003, 110));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule4", 104, 1004, 130));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule5", 104, 1005, 150));

            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule1", 105, 1001, 160));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule2", 105, 1002, 165));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule3", 105, 1003, 175));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule4", 105, 1004, 185));
            //ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule5", 105, 1005, 195));

            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule1", 11, 51, 4));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule2", 11, 52, 5));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule3", 11, 53, 25));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule4", 11, 54, 30));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule5", 11, 55, 20));

            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule1", 12, 51, 2));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule2", 12, 52, 4));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule3", 12, 53, 40));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule4", 12, 54, 50));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule5", 12, 55, 55));


            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule1", 13, 51, 90));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule2", 13, 52, 80));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule3", 13, 53, 70));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule4", 13, 54, 60));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule5", 13, 55, 110));


            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule1", 14, 51, 100));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule2", 14, 52, 105));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule3", 14, 53, 110));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule4", 14, 54, 130));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule5", 14, 55, 150));

            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule1", 15, 51, 120));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule2", 15, 52, 125));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule3", 15, 53, 135));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule4", 15, 54, 185));
            ItemSetPriceRuleSet.ItemSetPriceRuleList.Add(new ItemSetPriceRuleV1d0("rule5", 15, 55, 195));


            ItemOrderedPriceInfoSet = new ItemPriceInfoSetV1d0();
            ItemOrderedPriceInfoSet.Type = "NonSet";
            ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("A1", 11, 15));
            ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("A2", 12, 20));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("A3", 13, 25));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("A4", 14, 25));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("A5", 15, 25));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("A6", 14, 25));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("A7", 13, 25));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("A8", 12, 25));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("A9", 11, 25));

            ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("B1", 51, 190));
            ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("B2", 52, 290));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("B3", 53, 235));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("B4", 54, 40));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("B5", 55, 50));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("B6", 54, 60));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("B7", 53, 70));
            //ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("B8", 52, 150));
           // ItemOrderedPriceInfoSet.ItemPriceInfoList.Add(new ItemPriceInfoV1d0("B9", 52, 50));
        }

        private void button2_Click(object sender, EventArgs e)
        {
            float result=GetOptimalSetPrice(ItemSetPriceRuleSet, ItemOrderedPriceInfoSet);
            MessageBox.Show("最优套餐价格"+ result.ToString("F0"));
        }
        /// <summary>
        /// 得到最优套餐价格
        /// </summary>
        /// <param name="itemSetPriceRuleSetJson">套餐价格规则集json字符串</param>
        /// <param name="itemOrderedPriceInfoSetJson">已点菜品价格信息集json字符串</param>
        /// <returns></returns>
        public static float GetOptimallSetPrice(string itemSetPriceRuleSetJson,string itemOrderedPriceInfoSetJson)
        {
            float result = 0;
            string ruleListString = JsonConvert.SerializeObject(ItemSetPriceRuleSet);
            string priceInfoSetString = JsonConvert.SerializeObject(ItemOrderedPriceInfoSet);
            var ruleSet= JsonConvert.DeserializeObject<ItemSetPriceRuleSetV1d0>(ruleListString) as ItemSetPriceRuleSetV1d0;
            var priceInfoSet= JsonConvert.DeserializeObject<ItemPriceInfoSetV1d0>(priceInfoSetString) as ItemPriceInfoSetV1d0;
            result = GetOptimalSetPrice(ruleSet, priceInfoSet);
            float mainDishPriceSum = 0;
            priceInfoSet.ItemPriceInfoList.FindAll(x => x.ItemLevel < 50).ForEach(x => mainDishPriceSum += x.ItemPrice);
            return result+ mainDishPriceSum;
        }
        /// <summary>
        /// 得到最优套餐价格
        /// </summary>
        /// <param name="itemSetPriceRuleSet"></param>
        /// <param name="itemOrderedPriceInfoSet"></param>
        /// <returns></returns>
        private  static float GetOptimalSetPrice(ItemSetPriceRuleSetV1d0 itemSetPriceRuleSet,ItemPriceInfoSetV1d0 itemOrderedPriceInfoSet)
        {
            var ruleListList = GetSingleItemValidRuleListList(itemSetPriceRuleSet, itemOrderedPriceInfoSet);
            //得到笛卡尔积
            List<List<ItemSetPriceRuleV1d0>> result = Descartes<ItemSetPriceRuleV1d0>(ruleListList);
            float optimalSetPrice =99999;
            float sum = 0;
            string itemOrderedLevelsString = GetStringOfPriceInfoLevel(itemOrderedPriceInfoSet);
            foreach (var item in result)
            {
                bool isValid = CheckRuleListIsValid(item, itemOrderedLevelsString);
                if (isValid)
                {
                    sum = 0;
                    item.ForEach(x => sum += x.SubPrice);
                    if (sum < optimalSetPrice) optimalSetPrice = sum;
                }
            }
            return optimalSetPrice;
        }
        /// <summary>
        /// 检查套餐规则列表是否有效
        /// </summary>
        /// <param name="ruleList"></param>
        /// <param name="stringLevelOfItemOrdered">已点菜品按级别排序，连接成一个字符串</param>
        /// <returns></returns>
        public static bool CheckRuleListIsValid(List<ItemSetPriceRuleV1d0> ruleList, string stringLevelOfItemOrdered)
        {
            bool isValid = false;
            //剔除规则中的999
            //List<ItemSetPriceRuleV1d0> usingRuleList = ruleList.FindAll(x => x.MainLevel != 999);
            //得到规则列表的排序后级别字符串
            string stringOfLevel = GetStringOfRuleLevel(ruleList);
            //将规则列表级别字符串与已点菜品的级别字符串进行比较
            if (stringOfLevel.Equals(stringLevelOfItemOrdered)) isValid = true;
            return isValid;
        }
        /// <summary>
        /// 将规则的主级别和子级别进行排序，然后将级别拼接成一个字符串
        /// </summary>
        /// <param name="ruleList">规则列表</param>
        /// <returns>级别字符串</returns>
        public static string GetStringOfRuleLevel(List<ItemSetPriceRuleV1d0> ruleList)
        {
            List<short> levelList = new List<short>();
            foreach (var item in ruleList)
            {
                //剔除规则中的999 999意味着只有配菜，没有主菜
                if (item.MainLevel!=999) levelList.Add(item.MainLevel);
                levelList.Add(item.SubLevel);
            }
            //排序
            levelList.Sort((x, y) => -x.CompareTo(y));
            StringBuilder sb = new StringBuilder();
            levelList.ForEach(x =>sb.Append(x));
            return sb.ToString();
        }
        /// <summary>
        /// 按照级别对已点菜品进行排序，然后将级别拼接成一个字符串
        /// </summary>
        /// <param name="ItemOrderedPriceInfoSet">已点菜品价格信息集</param>
        /// <returns>级别字符串</returns>
        public static  string GetStringOfPriceInfoLevel(ItemPriceInfoSetV1d0 ItemOrderedPriceInfoSet)
        {
            List<short> levelList = new List<short>();
            levelList = ItemOrderedPriceInfoSet.ItemPriceInfoList.Select(x => x.ItemLevel).ToList();
            //排序
            levelList.Sort((x, y) => -x.CompareTo(y));
            StringBuilder sb = new StringBuilder();
            levelList.ForEach(x => sb.Append(x));
            return sb.ToString();
        }
        private bool CheckRuleIsValidAndRemove(ItemSetPriceRuleV1d0 rule, ItemPriceInfoSetV1d0 ItemOrderPriceInfoSet)
        {
            bool isValid = false;
            var findedMain = ItemOrderPriceInfoSet.ItemPriceInfoList.FirstOrDefault(x => x.ItemLevel == rule.MainLevel);
            var findedSub = ItemOrderPriceInfoSet.ItemPriceInfoList.FirstOrDefault(x => x.ItemLevel == rule.SubLevel);
            if (findedMain != null && findedSub != null)
            {
                isValid = true;
                ItemOrderPriceInfoSet.ItemPriceInfoList.Remove(findedMain);
                ItemOrderPriceInfoSet.ItemPriceInfoList.Remove(findedSub);
            }
            else isValid = false;
            return isValid;
        }
        /// <summary>
        /// 得到套餐规则的主级别和子机级别，都在已点菜品集中的规则集合
        /// </summary>
        /// <param name="ruleSet"></param>
        /// <param name="priceInfoSet"></param>
        /// <returns></returns>
        private ItemSetPriceRuleSetV1d0 GetValidRuleSet(ItemSetPriceRuleSetV1d0 ruleSet, ItemPriceInfoSetV1d0 priceInfoSet)
        {
            ItemSetPriceRuleSetV1d0 validItemSetPriceRuleSet = new ItemSetPriceRuleSetV1d0();
            foreach (var item in ruleSet.ItemSetPriceRuleList)
            {
                var findedMain = priceInfoSet.ItemPriceInfoList.FirstOrDefault(x => x.ItemLevel == item.MainLevel);
                var findedSub = priceInfoSet.ItemPriceInfoList.FirstOrDefault(x => x.ItemLevel == item.SubLevel);
                if (findedMain != null && findedSub != null) validItemSetPriceRuleSet.ItemSetPriceRuleList.Add(item);
            }
            return validItemSetPriceRuleSet;
        }
        /// <summary>
        /// 得到每个【配菜】菜品的对应的规则集
        /// </summary>
        /// <returns></returns>
        public static  List<List<ItemSetPriceRuleV1d0>> GetSingleItemValidRuleListList(ItemSetPriceRuleSetV1d0 ruleSet, ItemPriceInfoSetV1d0 priceInfoSet)
        {
            List<List<ItemSetPriceRuleV1d0>> ruleListList = new List<List<ItemSetPriceRuleV1d0>>();
            var subItemPriceInfoSet = GetSubItemPriceInfoSet(priceInfoSet);
            foreach (var item in subItemPriceInfoSet.ItemPriceInfoList)
            {
                List<ItemSetPriceRuleV1d0> ruleList = new List<ItemSetPriceRuleV1d0>();
                //规则集中配菜级别等于当前配菜菜品级别的规则，对当前配菜菜品才是有效的
                var filterSubLevelRuleList = ruleSet.ItemSetPriceRuleList.FindAll(x => x.SubLevel == item.ItemLevel);
                //再次进行筛选,规则列表中,主菜级别包含在已点菜品中,该规则才有效
                foreach(var rule in filterSubLevelRuleList)
                {
                    var finded = priceInfoSet.ItemPriceInfoList.FirstOrDefault(x => x.ItemLevel == rule.MainLevel);
                    if (finded != null) ruleList.Add(rule);
                }
                //增加一个特殊规则，有配菜，无主菜的情况,套餐价格为配菜原本价格
                ruleList.Add(new ItemSetPriceRuleV1d0("Special", 999, item.ItemLevel,item.ItemPrice));
                ruleListList.Add(ruleList);
            }
            return ruleListList;
        }
        
        /// <summary>
        /// 得到已点菜品中的主菜列表
        /// </summary>
        /// <param name="totalPriceInfoSet"></param>
        /// <returns></returns>
        private ItemPriceInfoSetV1d0 GetMainItemPriceInfoSet(ItemPriceInfoSetV1d0 totalPriceInfoSet)
        {
            ItemPriceInfoSetV1d0 mainSet = new ItemPriceInfoSetV1d0();
            mainSet.ItemPriceInfoList = totalPriceInfoSet.ItemPriceInfoList.FindAll(x => x.ItemLevel < 50);
            return mainSet;
        }
        /// <summary>
        /// 得到已点菜品中的配菜列表
        /// </summary>
        /// <param name="totalPriceInfoSet"></param>
        /// <returns></returns>
        public static  ItemPriceInfoSetV1d0 GetSubItemPriceInfoSet(ItemPriceInfoSetV1d0 totalPriceInfoSet)
        {
            ItemPriceInfoSetV1d0 subSet = new ItemPriceInfoSetV1d0();
            subSet.ItemPriceInfoList = totalPriceInfoSet.ItemPriceInfoList.FindAll(x => x.ItemLevel >= 50);
            return subSet;
        }
        /// <summary>
        /// 得到菜品级别已包含在有效规则集中的菜品的集合（未包含的菜品，无需进行套餐价格最优计算）
        /// </summary>
        /// <param name="validRuleSet"></param>
        /// <param name="priceInfoSet"></param>
        /// <returns></returns>
        private ItemPriceInfoSetV1d0 GetPriceInfoSetInRule(ItemSetPriceRuleSetV1d0 validRuleSet, ItemPriceInfoSetV1d0 priceInfoSet)
        {
            ItemPriceInfoSetV1d0 resultPriceInfoSet = new ItemPriceInfoSetV1d0();
            foreach(var item in priceInfoSet.ItemPriceInfoList)
            {
                var finded = validRuleSet.ItemSetPriceRuleList.FirstOrDefault(x => x.MainLevel == item.ItemLevel || x.SubLevel == item.ItemLevel);
                if(finded!=null)
                {
                    resultPriceInfoSet.ItemPriceInfoList.Add(item);
                }
            }
            return resultPriceInfoSet;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //套餐优惠规则列表json字符串
            string ruleListString = JsonConvert.SerializeObject(ItemSetPriceRuleSet.ItemSetPriceRuleList);
            //已点菜品价格信息列表json字符串
            string priceInfoSetString = JsonConvert.SerializeObject(ItemOrderedPriceInfoSet.ItemPriceInfoList);
            string resultJson = SetOptimalPriceCalculateHelperV1d0.GetOptimalPriceInfoList(ruleListString, priceInfoSetString);
            MessageBox.Show(resultJson);

            FileStream fs = new FileStream("d:/jsonExample.txt", FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            //开始写入
            sw.WriteLine(ruleListString);
            sw.WriteLine(priceInfoSetString);
            //清空缓冲区
            sw.Flush();
            //关闭流
            sw.Close();
            fs.Close();

        }
        private List<List<int>> GetListListOfLong(long source)
        {
            List<List<int>> result = new List<List<int>>();
            List<int> upLimitsList = GetEveryDigitOfLong(source);
            foreach(var number in upLimitsList)
            {
                result.Add(GetNaturalSequence(number));
            }
            return result;
        }
        private List<int> GetNaturalSequence(int number)
        {
            List<int> result = new List<int>();
            for(int i=0;i<number;i++)
            {
                result.Add(i);
            }
            return result;
        }
        /// <summary>
        /// 得到各配菜可用价格规则的总数，每个数位代表一个配菜的可用规则总数
        /// </summary>
        /// <returns></returns>
        private long GetUpLimitOfCombination(List<ItemSetPriceRuleSetV1d0> ruleSetList)
        {
            long result = 0;
            for(int i=0;i< ruleSetList.Count;i++)
            {
                result += (long)(Math.Pow(10, i) * ruleSetList[i].ItemSetPriceRuleList.Count);
            }
            return result;
        }
        /// <summary>
        /// 得到长整形每个数位的数字（小尾方式，高位在列表前面，低位在列表后面）
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        private List<int> GetEveryDigitOfLong(long source)
        {
            string stringLong = source.ToString();
            List<int> result = new List<int>();
            for(int i=0;i<stringLong.Length;i++)
            {
                result.Add((byte)(stringLong[i])-48);
            }
            return result;
        }
        /// <summary>
        /// 笛卡尔乘积
        /// </summary>
        public static List<List<T>> Descartes<T>(List<List<T>> lstSplit)
        {
            int count = 1;
            //lstSplit.ForEach(item => count *= item.Count);
            foreach(var item in lstSplit)
            {
                if (item.Count > 0) count *= item.Count;
            }

            var lstResult = new List<List<T>>();

            for (int i = 0; i < count; ++i)
            {
                var lstTemp = new List<T>();
                int j = 1;
                lstSplit.ForEach(item =>
                {
                    j *= item.Count;
                    lstTemp.Add(item[(i / (count / j)) % item.Count]);
                });
                lstResult.Add(lstTemp);
            }
            return lstResult;
        }
        /// <summary>
        /// 深度复制，利用序列化和反序列化的方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="RealObject"></param>
        /// <returns></returns>
        public static T Clone<T>(T RealObject)
        {
            using (Stream objectStream = new MemoryStream())
            {
                //利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制 
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(objectStream, RealObject);
                objectStream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(objectStream);
            }
        }
    }
}
